1. Technical Field
This invention relates to source code evaluation and software testing. More specifically, the invention relates to concentrating software testing for errors to a user-identified subset of the source code in order to maximize efficient use of test resources.
2. Description of the Prior Art
Source code is a sequence of program instructions in human-readable input format. More specifically, source code is primarily used as input to a process that produces an executable program. A branch is a point in a computer program, also known as set of program instructions, where the flow of control is altered. An instruction that causes a branch can be taken or not taken. If a branch is not taken, then the flow of control is unchanged, and the next instruction to be executed is the instruction immediately following the current instruction. However, if the branch is taken, the next instruction to be executed is an instruction at some other place in the code. There are two primary forms of branch instruction: a conditional branch and an unconditional branch. A conditional branch can either be taken or not taken depending on the condition, whereas an unconditional branch is always taken. One tool commonly employed in static analysis is known as a Control Flow Graph (CFG). Various execution paths may be represented in the CFG whose nodes represent basic blocks of sequentially-executing code, and whose connections (edges) between those nodes represent the branches that control the flow of program execution.
FIG. 1 is a block diagram (100) of a sample prior art CFG wherein each node in the graph represents a basic block, and edges are used to represent jumps in the control flow. More specifically, an entry point, “Start” indicates that node1, (102) will be the initial basic block to be executed. Node1 ends in a conditional branch which leads to one of two optional exit branches (104) and (106), also known as edges. The first edge (104) directs the flow to a second basic block shown as node2 (108), and the second edge (106) directs the flow to a third basic block shown as node3 (110). Based upon the edge selected, the execution paths diverge. More specifically, based upon this example, choosing the first edge (104) leads to the second basic block (108) which unconditionally leads to an exit point (112) from the CFG. Conversely, choosing the second edge (106) leads to the third basic block (110) which has two optional exit branches (114) and (116). The third edge (114) directs the flow to the fourth basic block shown as node4 (118), and the fourth edge (116) directs the flow to the fifth basic block shown as node5 (120). Each of the fourth and fifth basic blocks (118) and (120) are shown as having a single (i.e., unconditional) exit branch. More specifically, the fourth basic block (118) leads to the exit point from the code path (112), and the fifth basic block (120) has an exit branch (122) that leads to the fourth basic block (118). Aside from the basic blocks discussed above, the example herein contains a sixth basic block shown as node6 (124) that unconditionally leads to the exit point (112). As shown, there is no entry point from code execution for the sixth basic block, node6, (124). In other words, the code represented by the sixth basic block is not reachable.
A software bug is an error in some form in a computer program that prevents the program from behaving as intended. In other words, the bug causes the program to produce an unintended or incorrect result. Most bugs arise from oversights made by computer programmers during design, coding, and data entry. Occasionally, bugs are introduced via other sources such as compilers producing incorrect code. Bugs can have a wide variety of effects, with varying levels of inconvenience to the user of the program. Some bugs have only a subtle effect on the program's functionality, and may lie undetected for a long time, while other bugs may cause more serious program errors such as crashes or data corruption.
Software testing is the process of checking a computer program to verify that it behaves as intended. In other words, software testing attempts to verify that the computer program is free from bugs. Code coverage is a commonly used metric for evaluating the comprehensiveness of software testing. It measures how much of the program-under-test has been executed during the test process. In CFG terms, code coverage measures a percentage of nodes executed during the software test cycle.
It is known in the art that achieving full path code coverage in software testing requires an exhaustive checking of all branch conditions for all conditional branches. Achieving full path code coverage is extremely difficult, if not impossible for complex program. Exhaustively testing each conditional branch to ensure execution of all basic blocks is expensive and time consuming. At some point, there is a diminishing return on the cost of testing for bugs in basic blocks that are not frequently utilized, or which are deemed less critical for other reasons. For this reason, software test plans generally have code coverage objectives that fall short of full path coverage. For example, a project's personnel and schedule constraints might lead to an 80% code coverage goal for the project's software test cycle. A significant problem with this approach, however, is that there is generally no distinction made for which 20% of the code will go untested.
Therefore, in view of the foregoing, it would be advantageous to provide a method, system, and program for improving efficient use of finite software test resources by focusing testing on the subset of code deemed to be most important. In the aforementioned example, the test team might attempt to focus their testing on the code where the presence of undiscovered bugs is deemed most likely to cause serious consequences.